package algorithm.tree.multitree.inorder;


import algorithm.tree.multitree.base.MTreeNode;
import algorithm.tree.multitree.base.MTreeNodeEvent;

import java.util.List;
import java.util.Stack;
import java.util.function.Consumer;

public class MTreeInorderNonRecursion {
    public void traverse(MTreeNode node, int sequenceNum, Consumer<MTreeNode> consumer) {
        assert sequenceNum >= 0 : "sequenceNum needs to be greater than or equal to 0";
        Stack<MTreeNodeEvent<MTreeNode>> nodeStack = new Stack<>();
        nodeStack.push(new MTreeNodeEvent<>(0, node));
        while (!nodeStack.empty()) {
            MTreeNodeEvent<MTreeNode> event = nodeStack.pop();
            MTreeNode temp = event.data();
            switch (event.type()) {
                case 0 -> {
                    if (temp != null) {
                        List<MTreeNode> children = temp.getNodeList();
                        for (int i = children.size() - 1; i > sequenceNum; i--) {
                            nodeStack.push(new MTreeNodeEvent<>(0, children.get(i)));
                        }
                        nodeStack.push(new MTreeNodeEvent<>(1, temp));
                        for (int i = sequenceNum; i >= 0; i--) {
                            if (i <= children.size()) {
                                nodeStack.push(new MTreeNodeEvent<>(0, children.get(i)));
                            }
                        }
                    }
                }
                case 1 -> {
                    consumer.accept(temp);
                }
            }
        }
    }
}
